/* 
 * Copyright (C) 2014 Ningbo Yuanqun Inc., All Rights Reserved. 
 */
package com.yuanqunsoft.alimigration.common;

import java.io.File;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;

/**
 * <p>
 * 读取公共配置的工具类
 * </p>
 * 
 * @author ShaoYu
 *
 */
public final class PropertiesUtil {

    private static PropertiesConfiguration configuration;

    // 迁移至AWS时注意核查
    static {
        // loadProperties();
        try {
            configuration = new PropertiesConfiguration("common.properties");
            configuration.setAutoSave(true);
        } catch (ConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private PropertiesUtil() {

    }

    /**
     * <p>
     * Tests if the specified object is a key in this hashtable.
     * </p>
     * 
     * @param key
     *            possible key
     * @return true if and only if the specified object is a key in this hashtable, as determined by the equals
     *         method; false otherwise.
     */
    public static boolean containsKey(String key) {
        Helper.checkStringNullorEmpty(key, "key");
        return configuration.containsKey(key);
    }

    /**
     * <p>
     * 将 <code>key</code> 和 <code>value</code> 添加到公共配置文件中，这个操作会覆盖原有的配置。
     * </p>
     * 
     * <p>
     * 如果需要非覆盖性的操作，请使用 {@link #putIfNoSuchKey(String, String)}
     * </p>
     * 
     * @param key
     *            配置文件的键
     * @param value
     *            配置文件的值
     * @return 覆盖之前的值，如果没有值被覆盖则返回 <code>null</code>
     */
    public static Object put(String key, String value) {
        Object o = null;
        if (containsKey(key)) {
            o = configuration.getProperty(key);
        }
        configuration.setProperty(key, value);
        return o;
    }

    /**
     * <p>
     * 获取 <code>key</code> 对应的值
     * </p>
     * 
     * @param key
     *            配置文件的键
     * @return 配置文件的值
     */
    public static String getProperty(String key) {
        return configuration.getString(key);
    }

    /**
     * <p>
     * 获取 <code>key</code> 对应的值,如果值不存在，则返回默认值
     * </p>
     * 
     * @param key
     *            配置文件对应的键
     * @param defaultValue
     *            默认值
     * @return
     */
    public static String getProperty(String key, String defaultValue) {
        return configuration.getString(key, defaultValue);
    }

    /**
     * <p>
     * 如果原来不存在 <code>key</code> ，将 <code>key</code> 和 <code>value</code> 添加到公共配置文件中。 相对于
     * {@link #put(String, String)}，这是个非覆盖性的操作。
     * </p>
     * 
     * @param key
     *            配置文件的键
     * @param value
     *            配置文件的值
     * @return 是否插入成功
     */
    public static boolean putIfNoSuchKey(String key, String value) {
        Helper.checkStringNullorEmpty(key, "key");
        Helper.checkStringNullorEmpty(value, "value");
        boolean hasKey = configuration.containsKey(key);
        if (!hasKey) {
            configuration.addProperty(key, value);
            return true;
        }
        return hasKey;
    }

    /**
     * <p>
     * 获取上传待扫描应用的存放根目录
     * </p>
     * 
     * @return 待扫描应用存放根目录
     */
    public static File getApplicationUploadDir() {
        initApplicationUploadDir();
        String path = getProperty(GlobalConfig.ENGINE_PROPERTIES_SCAN_FILE_BASE_DIR);
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

    private static void initApplicationUploadDir() {
        if (!Boolean.valueOf(getProperty(GlobalConfig.ENGINE_PROPERTIES_IS_SCAN_FILE_BASE_DIR_INIT, "false"))) {
            String path = getProperty(GlobalConfig.ENGINE_PROPERTIES_SCAN_FILE_BASE_DIR);
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            put(GlobalConfig.ENGINE_PROPERTIES_SCAN_FILE_BASE_DIR, dir.getAbsolutePath());
            put(GlobalConfig.ENGINE_PROPERTIES_IS_SCAN_FILE_BASE_DIR_INIT, "true");
        }
    }

    /**
     * <p>
     * 根据传入的 <code>parseEngineType</code> 获取相应的目录
     * </p>
     * 
     * @param parseEngineType
     *            引擎的类型
     * @return 对应的目录文件
     */
    public static File getRuleImplClassDir(ParseEngineType parseEngineType) {
        initRuleImplClassDir();
        String based = getProperty(GlobalConfig.ENGINE_PROPERTIES_IMPLEMENT_CLASS_BASE_DIR);
        String subPath = getProperty(GlobalConfig.ENGINE_PROPERTIES_PACKAGE_PATH);
        subPath = subPath.replaceAll("\\.", "\\\\");
        String path = (based + File.separator + subPath + File.separator + parseEngineType).toLowerCase();
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

    private static void initRuleImplClassDir() {
        if (!Boolean
                .valueOf(getProperty(GlobalConfig.ENGINE_PROPERTIES_IS_IMPLEMENT_CLASS_BASE_DIR_INIT, "false"))) {
            String path = getProperty(GlobalConfig.ENGINE_PROPERTIES_IMPLEMENT_CLASS_BASE_DIR);
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            put(GlobalConfig.ENGINE_PROPERTIES_IMPLEMENT_CLASS_BASE_DIR, dir.getAbsolutePath());
            put(GlobalConfig.ENGINE_PROPERTIES_IS_IMPLEMENT_CLASS_BASE_DIR_INIT, "true");
        }
    }

    /**
     * <p>
     * 根据传入的 <code>parseEngineType</code> 获取相应的根目录，供core调用
     * </p>
     * 
     * @param parseEngineType
     *            引擎的类型
     * @return 对应的目录文件
     */
    public static File getRuleImplClassBasedDir() {
        String path = getProperty(GlobalConfig.ENGINE_PROPERTIES_IMPLEMENT_CLASS_BASE_DIR);
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

    /**
     * <p>
     * 获取上传规则实现类配置文件的存取目录
     * </p>
     * 
     * @return 规则实现类配置文件的存取目录
     */
    public static File getRuleImplPropertiesDir() {
        String based = getProperty(GlobalConfig.ENGINE_PROPERTIES_IMPLEMENT_CLASS_BASE_DIR);
        String propertiesPath = getProperty(GlobalConfig.ENGINE_PROPERTIES_IMPLEMENT_CONFIG_DIR);
        String path = based + File.separator + propertiesPath;
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

}
